import { app, shell, BrowserWindow, ipcMain, desktopCapturer, dialog } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
import screenshot from '../../native/build/Release/screenshot.node'
import createRecording from './recording'
import { stropNginx } from './nginx'
import Store from 'electron-store'
import fs from 'fs'
// Store.initRenderer()
export type StoreType = {
  settings: {
    videoFileSaved: string // 视频存放地址
    audioFileSaved: string // 音频存放地址
  }
}
export const store = new Store<StoreType>({
  defaults: {
    settings: {
      videoFileSaved: join(app.getPath('videos')),
      audioFileSaved: join(app.getPath('music'))
    }
  }
})
let screenshotData: {
  cutInfo: {
    width: number
    height: number
    startX: number
    startY: number
  }
  base64: string
}
function createWindow(): BrowserWindow {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 500,
    height: 270,
    show: false,
    frame: true,
    resizable: false, // 禁止调整大小
    maximizable: false,
    autoHideMenuBar: true,
    alwaysOnTop: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false,
      enableBlinkFeatures: 'MediaDevices'
    }
  })

  mainWindow.on('ready-to-show', () => {
    mainWindow.show()
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  console.log('ELECTRON_RENDERER_URL', process.env['ELECTRON_RENDERER_URL'])
  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.webContents.openDevTools()
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    mainWindow.loadURL(join(__dirname, '../../out/renderer/index.html'))
  }

  return mainWindow
}

// 创建截屏窗口
function createScreenshotWindow(parentWindow: BrowserWindow): BrowserWindow {
  const screenshotWindow = new BrowserWindow({
    parent: parentWindow,
    frame: false, // 无边框窗口
    transparent: true, // 透明背景
    fullscreen: true, // 全屏
    skipTaskbar: false, // 隐藏任务栏图标
    autoHideMenuBar: false, // 隐藏菜单栏
    resizable: false, // 禁止调整大小
    show: false,
    alwaysOnTop: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })
  screenshotWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    screenshotWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '#/shotScreen')
  } else {
    screenshotWindow.loadURL(join(__dirname, '../../out/renderer/index.html') + '#/shotScreen')
  }
  return screenshotWindow
}

// 创建一个预览截图的贴纸窗口
async function createViewShotScreenWindow(...args): Promise<BrowserWindow> {
  const [width = 300, height = 300] = args
  const viewShotScreenWindow = new BrowserWindow({
    width,
    height,
    minHeight: 300,
    minWidth: 300,
    frame: false, // 无边框窗口
    skipTaskbar: false, // 隐藏任务栏图标
    autoHideMenuBar: false, // 隐藏菜单栏
    resizable: true, // 可以调整大小
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      webSecurity: false, // 关闭同源
      nodeIntegration: true,
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })
  viewShotScreenWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    viewShotScreenWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '#/viewShotScreen')
  } else {
    viewShotScreenWindow.loadURL(join(__dirname, '../../out/renderer/index.html') + '#/viewShotScreen')
  }
  return viewShotScreenWindow
}

// 创建一个设置窗口
async function createSettingWindow(): Promise<BrowserWindow> {
  const settingWindow = new BrowserWindow({
    width: 500,
    height: 500,
    show: true,
    frame: true,
    resizable: false, // 禁止调整大小
    maximizable: false,
    autoHideMenuBar: true,
    alwaysOnTop: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      webSecurity: false, // 关闭同源
      nodeIntegration: true,
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })
  settingWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    settingWindow.webContents.openDevTools()
    settingWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '#/settingPage')
  } else {
    settingWindow.loadURL(join(__dirname, '../../out/renderer/index.html') + '#/settingPage')
  }
  return settingWindow
}

// 创建一个录音窗口
function createSoundRecordingWindow(): BrowserWindow {
  const windows = new BrowserWindow({
    width: 100,
    height: 100,
    show: true,
    frame: false,
    resizable: false, // 禁止调整大小
    maximizable: false,
    autoHideMenuBar: true,
    transparent: true, // 透明窗口变成圆形
    alwaysOnTop: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      webSecurity: false, // 关闭同源
      nodeIntegration: true,
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })
  windows.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    windows.webContents.openDevTools()
    windows.loadURL(process.env['ELECTRON_RENDERER_URL'] + '#/soundRecording')
  } else {
    windows.loadURL(join(__dirname, '../../out/renderer/index.html') + '#/soundRecording')
  }
  return windows
}

function createSerachFileWindow(): BrowserWindow {
  const serachFileWindow = new BrowserWindow({
    width: 500,
    height: 500,
    show: true,
    frame: true,
    resizable: false, // 禁止调整大小
    maximizable: false,
    autoHideMenuBar: true,
    alwaysOnTop: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      webSecurity: false, // 关闭同源
      nodeIntegration: true,
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })
  serachFileWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    serachFileWindow.webContents.openDevTools()
    serachFileWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '#/serachFilePage')
  } else {
    serachFileWindow.loadURL(join(__dirname, '../../out/renderer/index.html') + '#/serachFilePage')
  }
  return serachFileWindow
}

async function handleTakeScreenshot(screenshotWindow): Promise<void> {
  // 调用c+++截图库
  const imageBuffer = screenshot.capture()
  const base64 = `data:image/png;base64,${imageBuffer.toString('base64')}`
  screenshotWindow.webContents.send('watchscreenShot', base64)
  // 创建一个无边框窗口
  screenshotWindow.show()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  // startNginx()
  // 初始化配置文件
  // Set app user model id for windows
  electronApp.setAppUserModelId('com.electron')
  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  const mainWindow = createWindow()
  const screenshotWindow = createScreenshotWindow(mainWindow)
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  // IPC test
  // ipcMain.on('ping', () => console.log('pong'))
  ipcMain.handle('capture', async (_, payload) => {
    let result
    try {
      if (payload === 'capture-screen') {
        await handleTakeScreenshot(screenshotWindow)
      } else if (payload === 'recording') {
        const desktops = await desktopCapturer.getSources({
          types: ['screen', 'window'],
          thumbnailSize: { width: 0, height: 0 }
        })
        result = desktops
      } else if (payload === 'video') {
        console.log('video')
      } else if (payload === 'audio') {
        createSoundRecordingWindow()
      }
      return {
        result,
        success: true
      }
    } catch (e) {
      return {
        success: false,
        message: e
      }
    }
  })

  ipcMain.on('closeScreenShot', () => {
    screenshotWindow?.hide()
  })

  ipcMain.on('window-move', (event, payload) => {
    const webContents = event.sender
    const win = BrowserWindow.fromWebContents(webContents)
    win?.setPosition(payload.x, payload.y)
  })

  ipcMain.on('view-shot-screen', (event, payload) => {
    const webContents = event.sender
    const win = BrowserWindow.fromWebContents(webContents)
    if (payload === 'minimize') {
      win?.minimize()
    } else if (payload === 'close') {
      win?.close()
    } else if (payload === 'sticky') {
      win?.isAlwaysOnTop() ? win?.setAlwaysOnTop(false) : win?.setAlwaysOnTop(true)
    }
  })

  ipcMain.on('save-screenshot', async (_, payload) => {
    screenshotData = payload
    const { cutInfo: { width, height } = {} } = payload
    await createViewShotScreenWindow(width, height)
  })

  ipcMain.on('setIgnoreMouseEvents', () => {
    screenshotWindow?.setIgnoreMouseEvents(false)
  })
  ipcMain.handle('get-screenshot-data', async () => {
    return screenshotData
  })

  ipcMain.on('open:setting:win', async () => {
    await createSettingWindow()
  })

  ipcMain.handle('open-folder-dialog', async (): Promise<string | null> => {
    const result = await dialog.showOpenDialog(mainWindow, {
      properties: ['openDirectory']
    })
    if (!result.canceled) {
      return result.filePaths[0]
    }
    return null
  })

  ipcMain.on('open-serachFile-win', (_) => {
    createSerachFileWindow()
  })
  ipcMain.handle('get:file:list', () => {
    const audioFileSaved = store.get('settings').audioFileSaved
    const videoFileSaved = store.get('settings').videoFileSaved
    const resultFile = (file, dirPath) => ({ fileName: file, fileUrl: join(dirPath, file) }) // 完整路径})
    return {
      audioList: fs.readdirSync(audioFileSaved).map(file => resultFile(file, audioFileSaved)).filter(file => file.fileName.endsWith('.mp4')).reverse(),
      videoList: fs.readdirSync(videoFileSaved).map(file => resultFile(file, videoFileSaved)).filter(file => file.fileName.endsWith('.webm')).reverse()
    }
  })

  ipcMain.handle('remove:file', (_, filePath) => {
    try {
      fs.unlinkSync(filePath)
      return true
    } catch (e) {
      console.log(e)
      return false
    }
  })

  ipcMain.on('open:file', (_, filePath) => {
    shell.showItemInFolder(filePath)
  })
  ipcMain.handle('store:get', (_, key) => store.get(key))
  ipcMain.handle('store:set', (_, key, value) => store.set(key, value))
  ipcMain.handle('store:delete', (_, key) => store.delete(key))
  // ipcMain.on('open:roundRecording:win', () => {
  //   createSoundRecordingWindow()
  // })
  // 录制视频
  createRecording()
  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  !is.dev && stropNginx()
  if (process.platform !== 'darwin') {
    console.log('closeApp')
    app.quit()
  }
})

app.commandLine.appendSwitch('disable-3d-apis')
app.commandLine.appendSwitch('disable-gpu')
app.commandLine.appendSwitch('disable-software-rasterizer')
app.commandLine.appendSwitch('disable-gpu-compositing')
app.commandLine.appendSwitch('disable-gpu-early-init')
app.commandLine.appendSwitch('disable-gpu-memory-buffer-compositor-resources')
app.commandLine.appendSwitch('disable-gpu-rasterization')
app.commandLine.appendSwitch('disable-gpu-sandbox')
app.commandLine.appendSwitch('disable-gpu-memory-buffer-video-frames')
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
